package com.hgyc.mom.core.mybatis;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.base.CaseFormat;
import com.hgyc.mom.common.util.ObjectUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Objects;

/**
 * 利用注解+反射，将Query对象转换成Wrapper
 *
 * 工具类：将查询对象转换成MyBatisPlus中的QueryWrapper
 *
 * @param <T>
 */
public class QueryWrapperUtil<T> {

    /**
     * 将查询对象转换成MyBatisPlus中的QueryWrapper
     * @param query
     * @param <T>
     * @return
     */
    public static <T> QueryWrapper<T> build(Object query) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();

        //获取Query类中都有哪些属性
        final Field[] fields = query.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.getName().equals("serialVersionUID")) {
                continue;
            }
            //设置field的私有方法可以访问
            field.setAccessible(true);
            //对象query中该field的值
            Object fieldValue = null;
            try {
                //获取对象指定属性的值
                fieldValue = field.get(query);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

            //获取Query类属性的名称
            final String fieldName = field.getName();
            //获取Query类对应的表字段名
            final String columnName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, fieldName);
            //获取Query类属性上的注解
            final Annotation[] annotations = field.getAnnotations();

            //过滤条件
            if (ObjectUtils.isNotEmpty(fieldValue)) {
                if (annotations == null || annotations.length == 0) {
                    //如果属性上没有注解，默认是相等EQ
                    if (!field.getType().getSimpleName().equals("RangeBean")) {
                        //过滤掉RangeBean类型
                        queryWrapper.eq(columnName, fieldValue);
                    }else {
                        RangeBean rangeBean = (RangeBean) fieldValue;
                        queryWrapper.between(columnName, rangeBean.getStart(), rangeBean.getEnd());
                    }
                } else {
                    for (Annotation annotation : annotations) {
                        //获取Query类属性上的注解类型的字节码
                        final Class<? extends Annotation> annotationType = annotation.annotationType();
                        if (EQ.class == annotationType) {
                            EQ eq = (EQ) annotation;
                            fun(eq.logic(), queryWrapper);
                            queryWrapper.eq(columnName, fieldValue);
                            break;
                        } else if (Like.class == annotationType) {
                            Like like = (Like) annotation;
                            fun(like.logic(), queryWrapper);
                            queryWrapper.like(columnName, fieldValue);
                            break;
                        } else if (IN.class == annotationType) {
                            IN in = (IN) annotation;
                            fun(in.logic(), queryWrapper);
                            queryWrapper.in(columnName, fieldValue);
                            break;
                        } else if (NE.class == annotationType) {
                            NE ne = (NE) annotation;
                            fun(ne.logic(), queryWrapper);
                            queryWrapper.ne(columnName, fieldValue);
                            break;
                        } else if (Between.class == annotationType) {
                            Between between = (Between) annotation;
                            fun(between.logic(), queryWrapper);
                            RangeBean rangeBean = (RangeBean) fieldValue;
                            queryWrapper.between(columnName, rangeBean.getStart(), rangeBean.getEnd());
                            break;
                        }
                    }
                }
            }

            //排序字段
            for (Annotation annotation : annotations) {
                //获取Query类属性上的注解类型的字节码
                final Class<? extends Annotation> annotationType = annotation.annotationType();

                if (OrderByDesc.class == annotationType) {
                    queryWrapper.orderByDesc(columnName);
                } else if (OrderByAsc.class == annotationType) {
                    queryWrapper.orderByAsc(columnName);
                }
            }
        }
        return queryWrapper;
    }

    /**
     * 添加or关系
     * @param logic
     * @param queryWrapper
     * @param <T>
     */
    private static <T> void fun(String logic, QueryWrapper<T> queryWrapper) {
        if ("or".equalsIgnoreCase(logic)) {
            queryWrapper.or();
        }
    }

}
